/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package MouseSensorDriver;

import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Properties;
import java.util.TreeMap;
import java.util.TreeSet;
import java.util.logging.Level;
import java.util.logging.Logger;

/**
 *
 * @author Asko
 */
public class Calibrator {

    Properties prop = new Properties();
    public final static int ADC_CHANELL_0 = 0;
    public final static int ADC_CHANELL_1 = 1;
    public final static int ADC_CHANELL_2 = 2;
    public final static int ADC_CHANELL_3 = 3;
    public final static int MOUSE_SENSOR_X = 4;
    public final static int MOUSE_SENSOR_Y = 5;
    public final static int ES_MOTOR_POS_1 = 6;
    public final static int ES_MOTOR_TORQ_1 = 7;
    public final static int ES_MOTOR_POS_2 = 8;
    public final static int ES_MOTOR_TORQ_2 = 9;
    public final static int ES_MOTOR_POS_3 = 10;
    public final static int ES_MOTOR_TORQ_3 = 11;
    public final static int ES_MOTOR_POS_4 = 12;
    public final static int ES_MOTOR_TORQ_4 = 13;
    public final static int ES_ADC_CHANELL_1 = 14;
    public final static int ES_ADC_CHANELL_2 = 15;
    public final static int ES_ADC_CHANELL_3 = 16;
    public final static int ES_ADC_CHANELL_4 = 17;
    public final static int ES_TOR_ADC_CHANELL_1 = 18;
    public final static int ES_TOR_ADC_CHANELL_2 = 19;
    public final static int ES_TOR_ADC_CHANELL_3 = 20;
    public final static int ES_TOR_ADC_CHANELL_4 = 21;
    public final static int OS_MOTOR_POS_1 = 22;
    public final static int OS_MOTOR_POS_2 = 23;
    public final static int OS_MOTOR_POS_3 = 24;
    public final static int OS_MOTOR_POS_4 = 25;
    public final static int OS_MOTOR_TORQ_1 = 26;
    public final static int OS_MOTOR_TORQ_2 = 27;
    public final static int OS_MOTOR_TORQ_3 = 28;
    public final static int OS_MOTOR_TORQ_4 = 29;
    public final static int OS_ADC_CHANNEL_1 = 30;
    public final static int OS_ADC_CHANNEL_2 = 31;
    public final static int OS_ADC_CHANNEL_3 = 32;
    public final static int OS_ADC_CHANNEL_4 = 33;
    public final static int OS_TOR_ADC_CHANNEL_1 = 34;
    public final static int OS_TOR_ADC_CHANNEL_2 = 35;
    public final static int OS_TOR_ADC_CHANNEL_3 = 36;
    public final static int OS_TOR_ADC_CHANNEL_4 = 37;
    /*Cupboards' sensors*/
    public final static int LAP_SENSOR_1_ENG = 38;
    public final static int LAP_SENSOR_2_ENG = 39;
    public final static int LAP_SENSOR_3_ENG = 40;
    public final static int LAP_SENSOR_4_ENG = 41;
    public final static int ENDO_SENSOR_1_ENG = 42;
    public final static int ENDO_SENSOR_2_ENG = 43;
    public final static int ENDO_SENSOR_3_ENG = 44;
    public final static int ENDO_SENSOR_4_ENG = 45;
    public final static int ENDO_SENSOR_1_ADC = 46;
    public final static int ENDO_SENSOR_2_ADC = 47;
    public final static int ENDO_SENSOR_3_ADC = 48;
    public final static int ENDO_SENSOR_4_ADC = 49;
    public final static int LAP_SENSOR_1_ADC = 50;
    public final static int LAP_SENSOR_2_ADC = 51;
    public final static int LAP_SENSOR_3_ADC = 52;
    public final static int LAP_SENSOR_4_ADC = 53;
    public final static int CAMERA_VERT = 54;
    public final static int CAMERA_HORZ = 55;
    public final static int CAMERA_LINE = 56;

    public final static int PARAMS_COUNT = 57;
    private static Calibrator calibrator = null;
    final String sep = File.separator;
    final String FILE_NAME = "." + sep + "coefs.ini";
    //final String DYNAMIC_COEFS = ".\\dynamicCoefs";
    double[] coefsOffset = new double[PARAMS_COUNT];
    double[] coefsProp = new double[PARAMS_COUNT];
    /*Массивы с коэффициентами*/
    double sensor_dynamicCoefs[][] = new double[4][];
    /*Количество точек*/
    double samplingInterval;
    int valsCnt = 100500;
    double adcVals[][] = new double[4][valsCnt];

    public Calibrator() {
        try {
            prop.load(new FileInputStream(FILE_NAME));
            for (int i = 0; i < PARAMS_COUNT; i++) {
                coefsOffset[i] = Double
                        .valueOf(prop.getProperty("coefOffset" + i, "0"));
                coefsProp[i] = Double
                        .valueOf(prop.getProperty("coefProp" + i, "1"));
            }
        } catch (IOException ex) {
            Logger.getLogger(Calibrator.class.getName()).log(Level.SEVERE, null, ex);
        }
    }

    public static void main(String[] args) {
        Calibrator calib = new Calibrator();
        calib.saveCoefs();
    }

    public void setCoefsOffset(int chNum, double val) {
        this.coefsOffset[chNum] = val;
    }

    public void setCoefsProp(int chNum, double val) {
        this.coefsProp[chNum] = val;
    }

    public double getCoefsProp(int chNum) {
        return coefsProp[chNum];
    }

    public double getCoefsOffset(int chNum) {
        return coefsOffset[chNum];
    }

    public int getSourceData(int chNum, double val) {
        return (int) Math.round((val - coefsOffset[chNum]) / coefsProp[chNum]);
    }

    public void saveCoefs() {
        try {
            for (int i = 0; i < PARAMS_COUNT; i++) {
                prop.setProperty("coefOffset" + i, "" + coefsOffset[i]);
                prop.setProperty("coefProp" + i, "" + coefsProp[i]);
            }
            prop.store(new FileOutputStream(FILE_NAME), "save");
        } catch (IOException ex) {
            Logger.getLogger(Calibrator.class.getName()).log(Level.SEVERE, null, ex);
        }
    }

    public double getData(int channelNum, long val) {
        return val * coefsProp[channelNum] + coefsOffset[channelNum];
    }

    public static Calibrator get() {
        if (calibrator == null) {
            calibrator = new Calibrator();
        }
        return calibrator;
    }

    public double getData(int chNumPos, int chNumProp, long val) {
        return coefsProp[chNumProp] * (val - coefsOffset[chNumPos])
                * (val - coefsOffset[chNumPos]) + coefsProp[chNumPos];
    }

    public int getSourceData(int chNumPos, int chNumProp, double val) {
        return (int) Math.round(Math.sqrt((val - coefsProp[chNumPos])
                / coefsProp[chNumProp]) - coefsOffset[chNumPos]);
    }

    public double getDynamicData(int sensorNum, int val, double meanVal) {
        double retVal = 0;
        if (val > meanVal) {
            retVal = sensor_dynamicCoefs[sensorNum][val];
        } else {
            retVal = sensor_dynamicCoefs[sensorNum][val] * 51;
        }
        return retVal;
    }

    public double getDynamicCoef(int chNum, int pos) {
        return 0;
    }
}
